﻿using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Xml.Linq;
using System.Xml.XPath;
using PengSW.NotifyPropertyChanged;
using PengSW.ObservableCollectionHelper;
using PengSW.XmlHelper;
using static PengSW.XmlHelper.XmlLinqHelper;

namespace PengSW.XmlImport
{
    public class RecordDefine : NotifyPropertyChangedObject, IXmlSeriable
    {
        public RecordDefine(TableDefine aTableDefine)
        {
            TableDefine = aTableDefine;
        }

        public TableDefine TableDefine { get; }

        public string RecordXPath { get { return _RecordXPath; } set { SetValue(ref _RecordXPath, value, nameof(RecordXPath)); } }
        private string _RecordXPath;

        public ObservableCollectionEx<FieldDefine> FieldDefines { get; } = new ObservableCollectionEx<FieldDefine>();

        public XElement CreateXElement(string aXmlNodeName)
        {
            return new XElement(aXmlNodeName,
                CreateXAttribute(nameof(RecordXPath), RecordXPath),
                from r in FieldDefines select r.CreateXElement(nameof(FieldDefine)));
        }

        public void ReadFromXml(XElement aXElement)
        {
            if (aXElement == null) return;
            RecordXPath = aXElement.GetAttributeValue(nameof(RecordXPath), null);

            FieldDefines.Clear();
            foreach (XElement aFieldDefineXElement in aXElement.Elements(nameof(FieldDefine)))
            {
                FieldDefine aFieldDefine = new FieldDefine(this);
                aFieldDefine.ReadFromXml(aFieldDefineXElement);
                FieldDefines.Add(aFieldDefine);
            }
        }

        private IEnumerable<XElement> GetRecordXElements(XElement aTableXElement)
        {
            string aRecordXPath = string.IsNullOrWhiteSpace(RecordXPath) ? "Record" : RecordXPath;
            return aTableXElement.XPathSelectElements(aRecordXPath);
        }

        public void Import(DataTable aTable, XElement aTableXElement)
        {
            // 根据字段定义准备数据表中的字段
            foreach (FieldDefine aFieldDefine in FieldDefines)
            {
                aFieldDefine.CreateField(aTable);
            }

            // 从记录节中提取记录内容
            IEnumerable<XElement> aRecordXElements = GetRecordXElements(aTableXElement);
            foreach (XElement aRecordXElement in aRecordXElements)
            {
                DataRow aDataRow = aTable.NewRow();
                foreach (FieldDefine aFieldDefine in FieldDefines)
                {
                    aFieldDefine.Import(aDataRow, aRecordXElement);
                }
                aTable.Rows.Add(aDataRow);
            }
        }
    }
}
